package com.data.hijack;

import java.io.File;
import java.io.IOException;
import java.util.*;

import org.apache.log4j.Logger;

import com.data.hijack.constant.Constants;
import com.data.hijack.context.HolderContext;
import com.data.hijack.readable.ReadablePlugin;
import com.data.hijack.util.*;

/**
 * @author husq
 */
public class HijackApplication {
    private static final Logger logger = Logger.getLogger(HijackApplication.class);

    /**
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            parseConfig();
        } catch (Exception e) {
            logger.error(TextUtils.format(e, "%s", "Parsing core configuration exceptions!"));
        }
        try {
            loadReadablePlugin();
        } catch (IOException e) {
            logger.error(TextUtils.format(e, "%s", "Loading data reading plugin exception!"));
        }

        ServiceBootStrap.boot();
    }

    /**
     * 
     * @throws Exception
     */
    private static void parseConfig() throws Exception {
        File file = FileUtils.getFile(Constants.SYSTEM_CONFIG_FILENAME, Constants.SYSTEM_CONFIG_FILENAME_SUFFIX,
            HijackApplication.class);
        Map<String, Object> m = AppUtils.LoadJson(file);
        Map<String, Object> map = new HashMap<>();
        otherCoreConfig(m, map);
        String bizNames = (String)m.get(Constants.BIZ_NAMES);
        List<String> list = TextUtils.split(bizNames, ',');
        List<String> bizNameList = new ArrayList<>();
        map.put(Constants.BIZ_NAMES, bizNameList);
        HolderContext.putOnlyPair(Constants.CONFIG_CONTEXT, map);
        for (int i = 0; i < list.size(); i++) {
            String bizName = list.get(i);
            if ("".equals(bizName.trim())) {
                continue;
            }
            bizNameList.add(bizName);

            Map tmp = new HashMap();
            map.put(bizName, tmp);
            Set<Map.Entry<String, Object>> set = m.entrySet();
            Iterator<Map.Entry<String, Object>> iter = set.iterator();
            while (iter.hasNext()) {
                Map.Entry<String, Object> me = iter.next();
                String key = me.getKey();
                Object value = me.getValue();
                if (Constants.BIZ_NAMES.equals(key)) {
                    continue;
                }
                int index = key.indexOf('.');
                if (index != -1) {
                    String k = key.substring(0, index);
                    if (bizName.equals(k)) {
                        tmp.put(key, value.toString().trim());
                    }
                }
            }
        }
    }

    private static void otherCoreConfig(Map<String, Object> src, Map<String, Object> dest) {
        String coreCount = (String)src.get(Constants.HANDLER_CORE_COUNT);
        String maxCount = (String)src.get(Constants.HANDLER_MAX_COUNT);

        dest.put(Constants.HANDLER_CORE_COUNT, coreCount);
        dest.put(Constants.HANDLER_MAX_COUNT, maxCount);

        executor(src, dest);

        HolderContext.putOnlyPair(Constants.CONFIG_CONTEXT, dest);
    }

    private static void executor(Map<String, Object> src, Map<String, Object> dest) {
        src.forEach((k, v) -> {
            if (k.contains(Constants.EXECUTORS)) {
                dest.put(k, v);
            }
        });
    }

    /**
     * 
     * @throws IOException
     */
    private static void loadReadablePlugin() throws IOException {
        File file = FileUtils.getFile(Constants.PLUGINS_REGESTER_FILENAME, "properties", HijackApplication.class);
        PropertiesReader propertiesReader = PropertiesReader.newInstance();
        propertiesReader.setFile(file);
        Properties properties = propertiesReader.getProperties();

        Map<String, Class<ReadablePlugin>> map = new HashMap();
        BeanUtils.createCacheClassFromConfig(map, properties);
        HolderContext.putOnlyPair(Constants.READABLE_PLUGIN_REGISTRY, map);
    }
}
